import {
  useCallback,
  FC,
  ReactElement,
  useEffect,
  useRef,
  useState,
  Fragment,
  createRef,
  useImperativeHandle,
} from "react";
import styled, { css, keyframes } from "styled-components";
import {
  createConnect,
  IWorldNews,
  queryWorldNews,
  sendWorldNews,
  SOCKET,
} from "../../api/worldNewsApi";
import { useAuth } from "../../context/AuthProvide";
import { ThemeFlexDiv } from "../BUI";
import Button from "../BUI/Button";
import { ThemeText } from "../BUI/View/ThemeView";
import WorldNewsItem from "./WorldNewsItem";
import AnimateCancelIcon from "./AnimateCancelIcon";
import Barrage from "./Barrage";

interface IProps {}

export const openMessageRef = createRef<{ open: () => void }>();

const WorldNews: FC<IProps> = (): ReactElement => {
  const { verifyAuth } = useAuth();
  const [open, setOpen] = useState(false);
  const [socket, setSocket] = useState<SOCKET | null>(null);
  const text = useRef<HTMLTextAreaElement>(null);
  const messageBox = useRef<HTMLDivElement>(null);
  const [worldNewsList, setWorldNewsList] = useState<IWorldNews[]>([]);
  const [barrage, setBarrages] = useState<IWorldNews | null>(null);

  const addNewNews = (data: IWorldNews) => {
    setWorldNewsList(prev => [...prev, data]);
    setBarrages(data);
  };

  // 开启socket连接 并获取最近20条消息
  const handleListenNews = useCallback(() => {
    const socket = createConnect();
    socket.on("connect", async () => {
      console.log("socket 连接成功");
      setSocket(socket);

      socket.on("haveNewNews", payload => {
        console.log(payload);
        const news = JSON.parse(payload);
        addNewNews(news);
      });

      const { data } = await queryWorldNews();
      if (!data) return;
      setWorldNewsList(data);
    });
  }, []);

  useEffect(() => {
    if (open && !socket) handleListenNews();
    // return () => {
    //   if (socket) {
    //     socket.disconnect();
    //     setSocket(null);
    //   }
    // };
  }, [open, socket, handleListenNews]);

  /**
   内容变化时自动滚动到最下面
   */
  useEffect(() => {
    const box = messageBox.current;
    if (box && open) {
      box.scrollTo(0, box.scrollHeight);
    }
  }, [worldNewsList, open]);

  const openMessage = useCallback(() => {
    setOpen(true);
  }, []);

  useImperativeHandle(openMessageRef, () => ({ open: openMessage }), [
    openMessage,
  ]);

  if (!open)
    return (
      <>
        {barrage ? <Barrage barrage={barrage} /> : null}
        <OpenButton onClick={openMessage}>世界消息</OpenButton>
      </>
    );

  const sendMessage = verifyAuth(async () => {
    const input = text.current as HTMLTextAreaElement;
    if (input.value) {
      const { data: news } = await sendWorldNews({ content: input.value });
      if (news) {
        addNewNews(news);
        socket?.emit("sendNews", JSON.stringify(news));
        input.value = "";
      }
    }
  });

  return (
    <Fragment>
      {barrage ? <Barrage barrage={barrage} /> : null}
      <Container>
        <ThemeFlexDiv column>
          <AnimateCancelIcon onClick={() => setOpen(false)} />
          <MessageBox ref={messageBox}>
            {worldNewsList.map(news => (
              <WorldNewsItem key={news._id} news={news} />
            ))}
          </MessageBox>
          <InputBox>
            <Input ref={text} placeholder="文明交流" />
            <Button onClick={sendMessage}>发送</Button>
          </InputBox>
        </ThemeFlexDiv>
      </Container>
    </Fragment>
  );
};

export default WorldNews;

const Input = styled.textarea`
  flex: 1;
  height: 2rem;
  padding: 0.5rem;
  transition: height 0.3s linear, background 0.3s linear;
  border: none;
  outline: none;
  border-radius: 5px;
  resize: none;
  background: #ccc;

  &:focus {
    height: 4rem;
    border: 1px solid ${props => props.theme.primary};
    background: #000;
    color: #fff;
  }
`;

const InputBox = styled.div`
  display: flex;
  align-items: flex-end;
  width: 100%;
  button {
    margin: 0 0.5rem;
    padding: 0 1rem;
  }
`;

const MessageBox = styled.div`
  flex: 1;
  margin-bottom: 0.5rem;
  overflow-x: hidden;
  overflow-y: scroll;
`;

const layout = css`
  position: fixed;
  bottom: 0.5rem;
  left: 0.5rem;
  z-index: ${props => props.theme.index.fixed};
`;

const scaleIn = keyframes`
  0%{transform:scale(0.8)}
  100%{transform:scale(1)}
`;

const Container = styled.div`
  ${ThemeText};
  ${layout};
  display: flex;
  width: 20rem;
  height: 25rem;
  animation: ${scaleIn} 0.3s linear;
  & > div {
    flex: 1;
    padding: 1rem;
    position: relative;
    border-radius: 1rem;
    box-shadow: 0 0 0.5rem 0
      ${props => (props.theme.mode == "dark" ? "#000" : "#666")};
  }

  @media (max-width: ${props => props.theme.media.phone}) {
    width: calc(100% - 1rem);
    height: 50vh;
    z-index: ${props => props.theme.index.emergeMobile};
    textarea {
      height: 3rem;
    }
    ${Button} {
      height: 3rem;
    }
  }
`;

const OpenButton = styled(Button)`
  ${layout};
  padding: 1rem 2rem;
  @media (max-width: ${props => props.theme.media.phone}) {
    display: none;
  }
`;
